///////////////////////////////////////////////////////////////////////////////
//
//    Copyright 2010-2012 Geoffrey TOURON (geoffrey.touron@gmail.com)
//
//    This file is part of Chasis.
//
//    Chasis is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Chasis is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Chasis.  If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////////

#include "messagequeue.hpp"

Messagequeue::Messagequeue()
{

}

Messagequeue::~Messagequeue()
{
	Message	*msg;

	while (!_mqin.empty())
	{
		msg = _mqin.front();
		if (msg->pckt)
			delete msg->pckt;
		delete msg;
		_mqin.pop();
	}
	while (!_mqout.empty())
	{
		msg = _mqout.front();
		if (msg->pckt)
			delete msg->pckt;
		delete msg;
		_mqout.pop();
	}
}

bool	Messagequeue::trylock_in()
{
	return (_mtxin.trylock());
}

void	Messagequeue::lock_in()
{
	_mtxin.lock();
}

void	Messagequeue::unlock_in()
{
	_mtxin.unlock();
}

bool	Messagequeue::trylock_out()
{
	return (_mtxout.trylock());
}

void	Messagequeue::lock_out()
{
	_mtxout.lock();
}

void	Messagequeue::unlock_out()
{
	_mtxout.unlock();
}

///////////////////////////////////////

void		Messagequeue::push_in_pckt(int cltid, float ping, int size, char *data)
{
	Message	*msg = new Message;

	msg->type = size == 4 ? DESTROY : UPDATE;
	msg->cltid = cltid;
	msg->actid = 0;
	msg->ping = ping;
	msg->pckt = new Packet(size, data);
	_mqin.push(msg);
}

void		Messagequeue::push_in_cnt(int cltid)
{
	Message	*msg = new Message;

	msg->type = CONNECTION;
	msg->cltid = cltid;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = 0;
	_mqin.push(msg);
}

void		Messagequeue::push_in_discnt(int cltid)
{
	Message	*msg = new Message;

	msg->type = DISCONNECTION;
	msg->cltid = cltid;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = 0;
	_mqin.push(msg);
}

void	Messagequeue::push_in_cntrl(int actid)
{
	Message	*msg = new Message;

	msg->type = CONTROL;
	msg->cltid = 0;
	msg->actid = actid;
	msg->ping = 0.0f;
	msg->pckt = 0;
	_mqin.push(msg);
}

void	Messagequeue::push_in_textmsg(int size, char *data)
{
	Message	*msg = new Message;

	msg->type = TEXTMSG;
	msg->cltid = 0;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = new Packet(size, data);
	_mqin.push(msg);
}

void	Messagequeue::push_in_textmsg(int cltid, int size, char *data)
{
	Message	*msg = new Message;

	msg->type = TEXTMSG;
	msg->cltid = cltid;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = new Packet(size, data);
	_mqin.push(msg);
}

///////////////////////////////////////

void		Messagequeue::push_out_pckt(Packet *pckt)
{
	Message	*msg = new Message;

	msg->type = UPDATE;
	msg->cltid = 0;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = pckt;
	_mqout.push(msg);
}

void		Messagequeue::push_out_pckt(int actorid)
{
	Message	*msg = new Message;

	msg->type = DESTROY;
	msg->cltid = 0;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = new Packet;
	msg->pckt->write(actorid);
	_mqout.push(msg);
}

void	Messagequeue::push_out_cnt(int cltid, int actid)
{
	Message	*msg = new Message;

	msg->type = CONNECTION;
	msg->cltid = cltid;
	msg->actid = actid;
	msg->ping = 0.0f;
	msg->pckt = 0;
	_mqout.push(msg);
}

void		Messagequeue::push_out_discnt(int cltid)
{
	Message	*msg = new Message;

	msg->type = DISCONNECTION;
	msg->cltid = cltid;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = 0;
	_mqout.push(msg);
}

void	Messagequeue::push_out_textmsg(std::string const &str)
{
	Message	*msg = new Message;

	msg->type = TEXTMSG;
	msg->cltid = 0;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = new Packet(str.length() + 1, str.c_str());
	_mqout.push(msg);
}

void	Messagequeue::push_out_textmsg(int cltid, std::string const &str)
{
	Message	*msg = new Message;

	msg->type = TEXTMSG;
	msg->cltid = cltid;
	msg->actid = 0;
	msg->ping = 0.0f;
	msg->pckt = new Packet(str.length() + 1, str.c_str());
	_mqout.push(msg);
}

///////////////////////////////////////

Messagequeue::Message	*Messagequeue::pop_in()
{
	Message				*msg;

	if (!_mqin.empty())
	{
		msg = _mqin.front();
		_mqin.pop();
		return (msg);
	}
	else
		return (0);
}

Messagequeue::Message	*Messagequeue::pop_out()
{
	Message				*msg;

	if (!_mqout.empty())
	{
		msg = _mqout.front();
		_mqout.pop();
		return (msg);
	}
	else
		return (0);
}
